home *** CD-ROM | disk | FTP | other *** search
/ CD Concept 6 / CD Concept 06.iso / mac / UTILITAIRE / Little Smalltalk v3.1.4 / C Source / Sources / macio.c < prev    next >
Text File  |  1995-01-26  |  10KB  |  417 lines

  1. /*
  2.     Little Smalltalk, version 2
  3.  
  4.     Unix specific input and output routines
  5.     written by tim budd, January 1988
  6.     
  7.     v3.1.0
  8.     ------
  9.     Converted for use with Macintosh by Julian Barkway, 
  10.     ⌐May 1994, all rights reserved.
  11. */
  12.  
  13. #include <stdio.h>
  14.  
  15. #include <string.h>
  16. #include "env.h"
  17. #include "memory.h"
  18. #include "names.h"
  19. #include "LStResources.h"
  20.  
  21. #include "macio.h"
  22. #include "memory.proto.h"
  23. #include "fileIn.proto.h"
  24. #include "news.proto.h"
  25. # ifdef TCL
  26. #   include "tclprim.proto.h"
  27. # else
  28. #   include "winprim.proto.h"
  29. # endif
  30.  
  31. static long fr(short fnum, char *p, long s);
  32. static void fw(short fnum, char *p, long s);
  33.  
  34. struct {
  35.     int            di;
  36.     object        cl;
  37.     short        ds;
  38. } dummyObject;
  39.  
  40.  
  41.  
  42. //===========================================================
  43. // Return a full pathname given the directory ID and Vol Ref.
  44. //===========================================================
  45. void getPathName (short volRef, long dirID, char *fullPath)
  46. {
  47.     CInfoPBRec    catInfo;
  48.     Str255        dirName;
  49.     OSErr        osErr;
  50.     
  51.     fullPath [0] = '\0';
  52.     catInfo.dirInfo.ioDrParID = dirID;
  53.     catInfo.dirInfo.ioNamePtr = dirName;
  54.     do {
  55.         catInfo.dirInfo.ioVRefNum   = volRef;
  56.         catInfo.dirInfo.ioFDirIndex = -1;
  57.         catInfo.dirInfo.ioDrDirID   = catInfo.dirInfo.ioDrParID;
  58.         osErr = PBGetCatInfo (&catInfo, FALSE);
  59.         PtoCstr (dirName);
  60.         strcat  ((char *)dirName, ":");
  61.         strcat  ((char *)dirName, fullPath);
  62.         strcpy  (fullPath, (char *)dirName);
  63.     } while (catInfo.dirInfo.ioDrDirID != 2);
  64. }
  65.  
  66.  
  67.  
  68. //======================================================
  69. // Return a full pathname given the working directory ID
  70. //======================================================
  71. void getPathNameFromWD (long dirID, char *fullPath)
  72. {
  73.     WDPBRec    wdInfo;
  74.     OSErr        osErr;
  75.     
  76.     fullPath [0] = '\0';
  77.     wdInfo.ioNamePtr  = NULL;
  78.     wdInfo.ioVRefNum  = (short)dirID;
  79.     wdInfo.ioWDIndex  = 0;
  80.     wdInfo.ioWDProcID = 0;
  81.     osErr = PBGetWDInfo (&wdInfo, FALSE);
  82.     if (osErr != noErr)
  83.         return;
  84.         
  85.     getPathName (wdInfo.ioWDVRefNum, wdInfo.ioWDDirID, fullPath);
  86. }
  87.  
  88.  
  89. //=========================================================
  90. // A version of fgets () using Mac, rather than C, file io.
  91. // (Probably better to read in the whole file, then parcel
  92. // lines out as required...)
  93. //=========================================================
  94. char *mac_fgets (char *buf, short n, FILE *fd)
  95. {
  96.     short    i = 0;
  97.     long    outCt;
  98.     OSErr    osErr;
  99.     
  100.     outCt = 1;
  101.     osErr = FSRead (fd->fileRef, &outCt, buf + i);
  102.     if (osErr != 0)
  103.         return NULL;
  104.  
  105.     while (   (buf [i] != '\n')
  106.            && (buf [i] != '\r')
  107.            && (i     <  n) ) {
  108.         i++; 
  109.         FSRead (fd->fileRef, &outCt, buf + i);
  110.     }
  111.  
  112.     if (buf [i] == '\n')
  113.         buf [i] = '\r';
  114.     buf [i + 1] = '\0';
  115.     
  116.     return buf;
  117. }
  118.  
  119.  
  120. //=========================================================
  121. // A version of fputs () using Mac, rather than C, file io.
  122. //=========================================================
  123. int mac_fputs (char *str, FILE *fd)
  124. {
  125.     long    outCt;
  126.     OSErr    osErr;
  127.     
  128.     outCt = (long)strlen (str);
  129.     osErr = FSWrite (fd->fileRef, &outCt, str);
  130.     if (osErr < 0)
  131.         return EOF;
  132.     
  133.     return 0;
  134. }
  135.  
  136.  
  137. //=======================================================
  138. //    imageRead - read in an object image
  139. //        we toss out the free lists built initially,
  140. //        reconstruct the linkages, then rebuild the free
  141. //        lists around the new objects.
  142. //        The only objects with nonzero reference counts
  143. //        will be those reachable from either symbols
  144. //=======================================================
  145. static long fr (short fnum, char *p, long s)
  146. {    
  147.     OSErr     r;
  148.     long    ct = s;
  149.  
  150.     r  = FSRead (fnum, &ct, p);
  151.     if ( r != 0L) {
  152.         if (ct != s && r != eofErr)
  153.             sysError ("imageRead count error", "");
  154.     }
  155.         
  156.     return r;
  157. }
  158.  
  159. noreturn imageRead (short fnum)
  160. {    
  161.     short         i, size;
  162.     object         *mBlockAlloc ();
  163.  
  164.     fr (fnum, (char *) &symbols, (long)sizeof(object));
  165.     i = 0;
  166.      while (fr (fnum, (char *)&dummyObject, (long)sizeof (dummyObject)) != eofErr) {
  167.         i = dummyObject.di;
  168.         
  169.         if ((i < 0) || (i > ObjectTableMax))
  170.             sysError("reading index out of range","");
  171.             
  172.         objectTable [i].class = dummyObject.cl;
  173.         if ( ( objectTable [i].class       < 0)
  174.         ||   ((objectTable [i].class >> 1) > ObjectTableMax) ) {
  175. //******    fprintf  ("index %d\n", dummyObject.cl);
  176.             sysError ("class out of range", "imageRead");
  177.         }
  178.         
  179.         objectTable [i].size = size = dummyObject.ds;
  180.         if (size < 0)
  181.             size = ((- size) + 1) / 2;
  182.         if (size != 0) {
  183.             objectTable [i].memory = mBlockAlloc ((int) size);
  184.             fr (fnum, (char *) objectTable [i].memory,
  185.                 sizeof (object) * (int) size);
  186.         }
  187.         else
  188.             objectTable[i].memory = (object *) 0;
  189.     }
  190.  
  191.     visit(symbols);        /* now restore ref counts, getting rid of unneeded junk */
  192.     setFreeLists();        /* toss out the old free lists, build new ones */
  193. }
  194.  
  195. //=======================================================
  196. //    imageWrite - write out an object image
  197. //=======================================================
  198.  
  199. static void fw (short fnum, char *p, long s)
  200. {
  201.     long    ct = s;
  202.     OSErr    r;
  203.     
  204.     r  = FSWrite (fnum, &ct, p);
  205.     if ( r != 0L
  206.     &&  ct != s  )
  207.         sysError ("imageWrite size error", "");
  208. }
  209.  
  210. void imageWrite (short fnum)
  211. {    
  212.     short i, size;
  213.  
  214.     fw (fnum, (char *)&symbols, (long)sizeof (object));
  215.  
  216.     for (i = 0; i < ObjectTableMax; i++) {
  217.         if (objectTable [i].referenceCount > 0) {
  218.             dummyObject.di = i;
  219.             dummyObject.cl = objectTable [i].class;
  220.             dummyObject.ds = size = objectTable [i].size;
  221.             fw (fnum, (char *)&dummyObject, sizeof (dummyObject));
  222.             if (size < 0) 
  223.                 size = ((- size) + 1) / 2;
  224.             if (size != 0) {
  225.                 fw (fnum, (char *)objectTable [i].memory,
  226.                     (long)sizeof (object) * size);
  227.             }
  228.         }
  229.     }
  230. }
  231.  
  232.  
  233.  
  234. #define MAXFILES     20
  235. #define OPEN_READ    1
  236. #define OPEN_WRITE    2
  237.  
  238. /* we assume this is initialized to NULL */
  239. static FILE fp [MAXFILES];
  240.  
  241. //===============================================================================
  242. // Following function just returns the file pointer associated with a file number 
  243. //===============================================================================
  244. FILE *getFilePointer (short fileNum)
  245. {
  246.     return &(fp [fileNum]);
  247. }
  248.  
  249.  
  250. //===============================================================================
  251. // Create a file to write to. 
  252. //===============================================================================
  253. OSErr createFile (Str255 *fname, short ft)
  254. {
  255.     unsigned long    fileType, secs;
  256.     Str255            tmp;
  257.     
  258.     stFileTypeToMac (ft, fileType);
  259.     
  260.         /* Create temporary file - hopefully with a unique file name! */
  261.         /* We'll rename it later...                                      */
  262.     PtoCstr     ((unsigned char *)fname);
  263.     strcat      ((char *)fname, "|");
  264.     GetDateTime (&secs);
  265.     NumToString (secs, tmp);
  266.     PtoCstr     (tmp);
  267.     strcat         ((char *)fname, (char *)tmp);    
  268.     CtoPstr     ((char *)fname);
  269.     return Create ((unsigned char *)fname, 0, kCreator, fileType);
  270. }
  271.  
  272.  
  273. //===============================================================================
  274. // Open a file for reading or writing.
  275. //===============================================================================
  276. OSErr openFile (FILE *fd, char *fname, char *openParms, short ftype)
  277. {
  278.     OSErr    osErr;
  279.     
  280.     CtoPstr (fname);
  281.     fd->openMode = OPEN_READ;
  282.     if (openParms [0] == 'w') {
  283.         osErr = createFile ((Str255 *)fname, ftype);
  284.         if (osErr != 0L) {
  285.             fd->openMode = 0;
  286.             goto error_exit;            /* Create failed */
  287.         }
  288.         fd->openMode = OPEN_WRITE;
  289.     }
  290.     osErr = FSOpen ((unsigned char *)fname, 0, &(fd->fileRef));
  291.     if (osErr != 0)
  292.         fd->openMode = 0;
  293.  
  294. error_exit:
  295.     PtoCstr ((unsigned char *)fname);
  296.     return osErr;
  297. }
  298.  
  299.  
  300. void closeFile (FILE *fd, char *fname)
  301. {
  302.     long        fsize;
  303.     Str255        tmp;
  304.     char        *str;
  305.     OSErr        osErr;
  306.     
  307.     if (fd->fileRef == 0)
  308.         return;
  309.         
  310.     FSClose  (fd->fileRef);
  311.     if (fd->openMode == OPEN_WRITE) {
  312.         FlushVol (NULL, 0);
  313.         GetEOF (fd->fileRef, &fsize);     /* Set file size */
  314.         SetEOF (fd->fileRef, fsize);
  315.         strcpy  ((char *)tmp, fname);
  316.         strtok  ((char *)tmp, "|");         /* Clip off our unique ID */
  317.         CtoPstr (fname);
  318.         CtoPstr ((char *)tmp);
  319.         osErr = FSDelete (tmp, 0);
  320.         if (osErr == 0L || osErr == fnfErr) {
  321.             Rename  ((unsigned char *)fname, 0,tmp);
  322.             PtoCstr ((unsigned char *)fname);
  323.             PtoCstr (tmp);
  324.             strcpy  (fname, (char *)tmp);
  325.         }
  326.     }
  327.     fd->openMode = 0;
  328.     fd->fileRef  = 0;
  329. }
  330.  
  331.  
  332.  
  333. //=========================================================
  334. //    Mac dependent file I/O primitives;
  335. //    basically, file numbers are all kept in a large array.
  336. //    File operations then just give an index into this array 
  337. //=========================================================
  338. object ioPrimitive (int number, object *arguments)
  339. {
  340.     short            i, j;
  341.     char            *p, buffer [1024], *openParms;
  342.     object            returnedObject;
  343.     OSErr            osErr;
  344.  
  345.     returnedObject = nilobj;
  346.     
  347.     i = intValue (arguments [0]);        /* p0 = Smalltalk file number */
  348.     switch (number) {
  349.         case 0:        /* file open: p1 = fname; p2 = open type; p3 = file type */
  350.             osErr = openFile (&fp [i], 
  351.                               charPtr  (arguments [1]), charPtr  (arguments [2]),
  352.                               intValue (arguments [3]));
  353.             if (osErr != 0L)
  354.                 returnedObject = nilobj;            /* Open failed */
  355.             else
  356.                 returnedObject = newInteger (i);
  357.             break;
  358.  
  359.         case 1:
  360.             closeFile (&fp [i], charPtr (arguments [1]));
  361.             break;
  362.  
  363.         case 2:        /* file size */
  364.         case 3:        /* file in */
  365.             if (fp [i].fileRef)
  366.                 fileIn (&fp [i], true);
  367.             break;
  368.  
  369.         case 4:        /* was Get Character - now Delete File */
  370.             p = charPtr  (arguments [1]);    /* Pathname of file to delete */
  371.             CtoPstr (p);
  372.             osErr = FSDelete ((unsigned char *)p, 0);
  373.             if (osErr == 0L)
  374.                 returnedObject = falseobj;
  375.             else
  376.                 returnedObject = trueobj;    /* returns true if error */
  377.             break;
  378.             
  379.         case 5:        /* get string */
  380.             if (fp [i].fileRef == 0)
  381.                 break;
  382.             j          = 0;
  383.             buffer [j] = '\0';
  384.             while (1) {
  385.                 if (mac_fgets (&buffer [j], 512, &fp [i]) == NULL)
  386.                     return nilobj;                            /* end of file */
  387.                 j = strlen(buffer)-1;
  388.                 if (buffer[j] != '\\')    // Unix???
  389.                     break;
  390.                /* else we loop again */
  391.             }
  392.             returnedObject = newStString (buffer);
  393.             break;
  394.  
  395.         case 7:        /* write an object image */
  396.             if (fp [i].fileRef)
  397.                 imageWrite (fp [i].fileRef);
  398.             returnedObject = trueobj;
  399.             break;
  400.  
  401.         case 8:        /* write a string to a file with no <cr> */
  402.         case 9:        /*  write a string, adding a <cr> */
  403. //******    if (! fp[i])
  404. //******        break; 
  405.             mac_fputs (charPtr (arguments [1]), &fp [i]);
  406.             if (number == 9)
  407.                 mac_fputs ("\r", &fp [i]);
  408.             break;
  409.  
  410.         default:
  411.             sysError ("unknown primitive", "filePrimitive");
  412.         }
  413.  
  414.     return returnedObject;
  415. }
  416.  
  417.